#ifndef GIGECAM_H
#define GIGECAM_H

#include <QObject>
#include <QSize>
#include <QStringList>
#include <QImage>
#include "tisudshl.h"
#include "SimplePropertyAccess.h"
#include <algorithm>
using namespace DShowLib;

class CameraListener;
class GigECam;

class GigECam : public QObject
{
    Q_OBJECT
public:
    explicit GigECam(QObject *parent = 0);
    ~GigECam();
    bool initLibrary();
    bool initFrameHandlerSink();
    bool selectDevice();
    void closeDevice();
    bool openDefaultDevice();
    bool loadDeviceStateFromFile(const std::string& filename, bool bOpenDev = true);
    bool saveDeviceStateToFile( const std::string& filename);

    bool openDevice(__int64 id);
    bool openDevice(QString devString);
    bool setVideoFormat(QString format);
    __int64 getCameraID(int index);
    QStringList listDeviceUniqueName();
    QStringList listVideoFormat();
    bool showVCDPropertyPage( );
    /**
    * @brief 开始采集图像
    * @param show  true 表示打开一个新的窗口显示视频， false 则不打开新的窗口
    * @return true 表示图像采集正常，false 表示图像采集失败
    */
    bool startLive(bool show = true);
    bool stopLive();
    bool isValid();
    bool suspendLive();
    void initFrameRate();
    void initVCDPropertyAccess();
    bool autoBrightness(bool on);
    bool autoWhiteBalance(bool on);

    bool onePush();

    double frameRate();
    int expoureTime();
private:
    static bool m_libState;
    DShowLib::Grabber* m_pGrabber;
    Grabber::tVidCapDevListPtr m_pVidCapDevList;
    Grabber::tVidNrmListPtr m_pVidNrmList;
    Grabber::tVidFmtListPtr m_pVidFmtList;
    CameraListener *m_pListener;
    DShowLib::FrameTypeInfoArray m_acceptedTypes;
    smart_ptr<FrameHandlerSink> m_pFrameHandlerSink;
    CSimplePropertyAccess m_VCDProp;

    // 相机支持的帧速率，及当前的帧速率
    Grabber::tFPSListPtr  m_pFrameRateList;
    double m_framerate;

    float m_exposureTime;
    float m_minExposureTime;
    float m_maxExposureTime;

    bool m_autoBrightness;
    bool m_autoWhiteBalance;
signals:
    void Mono8ImageChanged(const unsigned char *pBuf, QSize size);
    void RGB24ImageChanged(const unsigned char *pBuf, QSize size);
    void RGB32ImageChanged(const unsigned char *pBuf, QSize size);
    void imageChanged(QImage image);
    void deviceLost();
public slots:
    void setFrameRate(double fps);
    void setBrightness(int value);
    void setWhiteBalance(int red, int blue);
    bool setExpoureTime(int value);
};

class CameraListener : public DShowLib::GrabberListener
{
public:
    explicit CameraListener(GigECam *pCamera, SIZE size);
    //explicit CameraListener(GigECam *pCamera);
    ~CameraListener();
    GigECam * m_pCamera;
    QImage m_image;
public:
    // Overwrite the GrabberListener methods we need
    void frameReady( DShowLib::Grabber& caller, smart_ptr<DShowLib::MemBuffer> pBuffer, DWORD FrameNumber );
    void deviceLost( Grabber& caller );
};
#endif // GIGECAM_H
